//
//  BLEManager.m
//  OC-Example
//
//  Created by apang on 2018/7/31.
//  Copyright © 2018年 apang.men All rights reserved.
//

#import "BLEManager.h"
#import <UIKit/UIKit.h>

@interface BLEManager ()<CBCentralManagerDelegate,CBPeripheralDelegate>
/**
 中心管理者
 */
@property (nonatomic, strong) CBCentralManager *centralManager;
/**
 发现设备回调
 */
@property (nonatomic, copy) BLEDiscoverPeripheral discoverPeripheral;
/**
 连接设备回调
 */
@property (nonatomic, copy) BLEPeripheralConnect peripheralConnect;
@end

@implementation BLEManager
//MARK:单利的实现
+(BLEManager *)sharedManager {
    static BLEManager *_manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [[BLEManager alloc] init];
    });
    return _manager;
}

+ (void)load {
    [BLEManager sharedManager];
}
- (instancetype)init {
    
    if (self = [super init]) {
        //MARK:CBCentralManagerOptionShowPowerAlertKey 蓝牙未打开的时候是否提示用户
        //MARK:CBCentralManagerOptionRestoreIdentifierKey 恢复连接，value 为NSUUID
        //TODO:恢复连接
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey:@YES}];
    }
    return self;
}

#pragma mark CBCentralManager'Delegate

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    //MARK:蓝牙状态改变
    //TODO:状态提示
    switch (central.state) {
        case CBCentralManagerStateUnknown:
        case CBCentralManagerStateResetting:
        case CBCentralManagerStateUnsupported:
        case CBCentralManagerStateUnauthorized:{
            [BLEManager checkPermission];
        }
            break;
        case CBCentralManagerStatePoweredOff:
            break;
        case CBCentralManagerStatePoweredOn:
            break;
            
        default:
            break;
    }
}

// TODO:恢复连接
//- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *, id> *)dict;

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI {
    //MARK:发现设备
    //TODO:RSSI信号
    ExLog(@"发现设备 name:%@ uuid:%@ RSSI:%@",peripheral.name,peripheral.identifier,RSSI);
    if(_discoverPeripheral)_discoverPeripheral(peripheral);
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    //MARK:连接设备
    ExLog(@"设备连接成功");
    [self stopScan];
    _connectState = BLEConnectStateSuccess;
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
    if(_peripheralConnect)_peripheralConnect(BLEConnectStateSuccess,nil);
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error {
    //MARK:连接设备失败
    ExLog(@"连接设备失败");
    _connectState = BLEConnectStateFailure;
    if(_peripheralConnect)_peripheralConnect(BLEConnectStateFailure,error);
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error {
    //MARK:断开连接
    ExLog(@"断开连接");
    _connectState = BLEConnectStateDisconnect;
    if(_peripheralConnect)_peripheralConnect(BLEConnectStateDisconnect,error);
}

#pragma mark CBPeripheral'Delegate
- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral {
    //MARK:更新名称
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray<CBService *> *)invalidatedServices {
    //MARK:服务更改
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(nullable NSError *)error {
    //MARK:设备信号
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error {
    //MARK:设备被更改后，会调用发现服务回调
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverIncludedServicesForService:(CBService *)service error:(nullable NSError *)error {
    //MARK:获取服务
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {
    //MARK:发现服务特征
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    //MARK:服务特征更新
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    //MARK:设置特征值
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    //MARK:服务特征状态通知
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    //MARK:服务特征描述信息
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(nullable NSError *)error {
    //MARK:描述更新
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(nullable NSError *)error {
    //MARK:
    ExLog(@"%s",__FUNCTION__);
}

- (void)peripheralIsReadyToSendWriteWithoutResponse:(CBPeripheral *)peripheral {
    //MARK:
    ExLog(@"%s",__FUNCTION__);
}

#pragma mark Custom'method

- (void)startScan:(BLEDiscoverPeripheral)discoverPeripheral {
    if([BLEManager checkPermission]){
        _discoverPeripheral = discoverPeripheral;
        //MARK:CBCentralManagerScanOptionAllowDuplicatesKey 是否过滤重复设备
        //MARK:CBCentralManagerScanOptionSolicitedServiceUUIDsKey 扫描包含特定服务的设备(CBUUID,服务CBUUID数组)
        [_centralManager scanForPeripheralsWithServices:nil options:nil];
    }
}

- (void)stopScan {
    [_centralManager stopScan];
    _discoverPeripheral = nil;
}

- (void)connectPeripheral:(CBPeripheral *)peripheral connectBlock:(BLEPeripheralConnect)connectBlock {
    _peripheralConnect = connectBlock;
    //MARK:CBConnectPeripheralOptionNotifyOnConnectionKey连接成功
    //MARK:CBConnectPeripheralOptionNotifyOnDisconnectionKey断开连接
    //MARK:CBConnectPeripheralOptionNotifyOnNotificationKey所有
    [_centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnNotificationKey:@YES}];
}

+ (BOOL)checkPermission {
    
    BOOL enable = NO;
    
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString * appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    appName = (appName.length>0)?appName:[infoDictionary objectForKey:@"CFBundleExecutable"];
    UIAlertAction * sureAction = nil;
    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
    NSString * message = @"";
    switch ([BLEManager sharedManager].centralManager.state) {
        case CBCentralManagerStateUnknown:
            message = @"请检查蓝牙状态";
            break;
        case CBCentralManagerStateResetting:
            message = @"蓝牙启动中";
            break;
        case CBCentralManagerStateUnauthorized:
        case CBCentralManagerStatePoweredOff:{
            message = [NSString stringWithFormat:@"打开蓝牙并允许\"%@\"连接到配件",appName];
            sureAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];//App-prefs:root=Bluetooth>9.0>App-prefs:root=General&path=Bluetooth
                if (@available(iOS 10.0, *)) {//App-prefs:root=LOCATION_SERVICES
                    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
                } else {
                    [[UIApplication sharedApplication]openURL:url];
                }
            }];
        }
            break;
        case CBCentralManagerStateUnsupported:
            message = @"不支持蓝牙";
            break;
        case CBCentralManagerStatePoweredOn:
            enable = YES;
            break;
        default:
            break;
    }
    if (message.length>1) {
        UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:message message:@"" preferredStyle:UIAlertControllerStyleAlert];
        if (sureAction) {
            [alertVC addAction:sureAction];
        }
        [alertVC addAction:cancelAction];
        [[[[UIApplication sharedApplication] delegate] window].rootViewController presentViewController:alertVC animated:YES completion:nil];
    }
    
    return enable;
}
@end
